package com.fjzzct.report.dao.Impl;

import com.fjzzct.report.dao.BaseDao;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.jdbc.core.namedparam.BeanPropertySqlParameterSource;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
import org.springframework.jdbc.core.namedparam.SqlParameterSource;
import org.springframework.jdbc.support.GeneratedKeyHolder;
import org.springframework.jdbc.support.KeyHolder;

import javax.annotation.Resource;
import javax.sql.DataSource;
import java.io.Serializable;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

public class BaseDaoImpl implements BaseDao
{

    public NamedParameterJdbcTemplate njdbcTemplate;

    // 数据库实例化，通过注解@Resource 将dataSource 实例化
    @Resource(name = "dataSource")
    public void setDataSource(DataSource dataSource)
    {
        this.njdbcTemplate = new NamedParameterJdbcTemplate(dataSource);
    }

    public <T extends Serializable> void saveOrUpdateObjectByMap(String sql, HashMap<String, Object> paramMap)
    {
        njdbcTemplate.update(sql, paramMap);
    }

    public <T extends Serializable> void saveOrUpdateObject(String sql, T entry)
    {
        SqlParameterSource ps = new BeanPropertySqlParameterSource(entry);
        KeyHolder keyholder = new GeneratedKeyHolder();
        njdbcTemplate.update(sql, ps, keyholder);
    }

    public <T extends Serializable> Integer saveOrUpdateObjectReturnIden(String sql, T entry)
    {
        SqlParameterSource ps = new BeanPropertySqlParameterSource(entry);
        KeyHolder keyholder = new GeneratedKeyHolder();
        njdbcTemplate.update(sql, ps, keyholder);
        return keyholder.getKey().intValue();
    }

    public <T extends Serializable> List<T> getObjList(String sql,
            Class<T> className, HashMap<String, Object> paramMap)
    {
        RowMapper<T> rm = BeanPropertyRowMapper.newInstance(className);
        return njdbcTemplate.query(sql, paramMap, rm);
    }

    @Override
    public <T extends Serializable> List<T> getObjListByProc(String procName, Class<T> className, HashMap<String, Object> paramMap)
    {
        RowMapper<T> rm = BeanPropertyRowMapper.newInstance(className);
        String sql = this.getSqlStr(procName, paramMap);
        return njdbcTemplate.query(sql, paramMap, rm);
    }

    public <T extends Serializable> T getObject(String sql, final Class<T> clazz, HashMap<String, Object> paramMap)
    {
        RowMapper<T> rm = BeanPropertyRowMapper.newInstance(clazz);
        return njdbcTemplate.queryForObject(sql, paramMap, rm);
    }

    public Map<String, ?> find(String sql, HashMap<String, Object> paramMap)
    {
        return njdbcTemplate.queryForMap(sql, paramMap);
    }


    public void batchOperate(String sql, Map<String, ?>[] paramMap)
    {
        njdbcTemplate.batchUpdate(sql, paramMap);
    }

    public void batchOperate(String sql, SqlParameterSource[] batchArgs)
    {
        njdbcTemplate.batchUpdate(sql, batchArgs);
    }

    public int isExist(String sql, HashMap<String, Object> paramMap)
    {
        return njdbcTemplate.queryForObject(sql, paramMap, Integer.class);
    }

    public int editObject(String sql, HashMap<String, Object> paramMap)
    {
        return njdbcTemplate.update(sql, paramMap);
    }

    private String getSqlStr(String procName, Map<String, Object> mapParams)
    {
        String sResult = "";
        if (mapParams == null || mapParams.size() == 0)
        {
            sResult = "CALL " + procName + "()";
        }
        else
        {
            StringBuffer buffer = new StringBuffer();
            buffer.append("CALL ");
            buffer.append(procName);
            buffer.append("(");
            Map<String, Object> map = new LinkedHashMap<String, Object>(mapParams);
            for (Map.Entry<String, Object> en : map.entrySet())
            {
                String sKey = en.getKey();
                buffer.append(":" + sKey + ",");
            }
            buffer.delete(buffer.length() - 1, buffer.length());
            buffer.append(")");
            sResult = buffer.toString();
            buffer.setLength(0);
        }
        return "{" + sResult + "}";
    }

}
